/*! \file nmea.c \brief NMEA protocol function library. */
//*****************************************************************************
//
// File Name	: 'nmea.c'
// Title		: NMEA protocol function library
// Author		: Pascal Stang - Copyright (C) 2002
// Created		: 2002.08.27
// Revised		: 2002.08.27
// Version		: 0.1
// Target MCU	: Atmel AVR Series
// Editor Tabs	: 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested.  Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
//		which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************

#ifndef WIN32
	#include <avr/io.h>
	#include <avr/interrupt.h>
	#include <avr/pgmspace.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>

#include "buffer.h"
#include "rprintf.h"

#include "nmea.h"

// Program ROM constants

// Global variables
s08 NmeaPacket[NMEA_BUFFERSIZE];

u08 nmeaProcess(cBuffer* rxBuffer, GpsInfoType * GpsInfo)
{
	u08 foundpacket = NMEA_NODATA;
	u08 startFlag = FALSE;
	//u08 data;
	u16 i,j;
	
		
	// process the receive buffer
	// go through buffer looking for packets
	while(rxBuffer->datalength)
	{
		// look for a start of NMEA packet
		if(bufferGetAtIndex(rxBuffer,0) == '$')
		{
			// found start
			startFlag = TRUE;
			// when start is found, we leave it intact in the receive buffer
			// in case the full NMEA string is not completely received.  The
			// start will be detected in the next nmeaProcess iteration.
			
			// done looking for start
			break;
		}
		else
		{
			bufferGetFromFront(rxBuffer);
		}
	}
	
	// if we detected a start, look for end of packet
	if(startFlag)
	{
		for(i=1; i<(rxBuffer->datalength)-1; i++)
		{
			// check for end of NMEA packet <CR><LF>
			if(((bufferGetAtIndex(rxBuffer,i) == '\r') && (bufferGetAtIndex(rxBuffer,i+1) == '\n')) || (bufferGetAtIndex(rxBuffer,i) == '\0'))
			{
				// have a packet end
				// dump initial '$'
				bufferGetFromFront(rxBuffer);
				// copy packet to NmeaPacket
				for(j=0; j<(i-1); j++)
				{
					// although NMEA strings should be 80 characters or less,
					// receive buffer errors can generate erroneous packets.
					// Protect against packet buffer overflow
					if(j<(NMEA_BUFFERSIZE-1))
						NmeaPacket[j] = bufferGetFromFront(rxBuffer);
					else
						bufferGetFromFront(rxBuffer);
				}
				// null terminate it
				NmeaPacket[j] = 0;
				// dump <CR><LF> from rxBuffer
				bufferGetFromFront(rxBuffer);
				bufferGetFromFront(rxBuffer);

				// found a packet
				// done with this processing session
				foundpacket = NMEA_UNKNOWN;
				break;
			}
		}
	}

	if(foundpacket)
	{
		// check message type and process appropriately
		if(!strncmp(NmeaPacket, "GPGGA", 5))
		{
			// process packet of this type
			nmeaProcessGPGGA(NmeaPacket, GpsInfo);
			// report packet type
			foundpacket = NMEA_GPGGA;
		}
	}
	else if(rxBuffer->datalength >= rxBuffer->size)
	{
		// if we found no packet, and the buffer is full
		// we're logjammed, flush entire buffer
		bufferFlush(rxBuffer);
	}
	return foundpacket;
}

void nmeaProcessGPGGA(s08* packet, GpsInfoType * gpsData)
{	
	char * delim = {","};
   	char * dotDelim = {"."};
	char * token = NULL;

	char * strtokPtr = NULL;

	char hourStr[14], latStr[14], longStr[14], altStr[10];

	strtok_r(packet,delim,&strtokPtr);
	token=(char *)strtok_r(NULL,delim,&strtokPtr);
	strcpy(hourStr, token);
	token=(char *)strtok_r(NULL,delim,&strtokPtr);
	strcpy(latStr,token);
	token=(char *)strtok_r(NULL,delim,&strtokPtr);
	gpsData->latLetter=token[0];
	token=(char *)strtok_r(NULL,delim,&strtokPtr);
	strcpy(longStr, token);
	token=(char *)strtok_r(NULL,delim,&strtokPtr);
	gpsData->longLetter=token[0];
	strtok_r(NULL,delim,&strtokPtr);
	strtok_r(NULL,delim,&strtokPtr);

	/*strtok_r(NULL,delim,&strtokPtr);*/ /*it depends of GPS used!!!*/

	token=(char *)strtok_r(NULL,delim,&strtokPtr);
	strcpy(altStr,token);

	gpsData->hour=atoi((char *)strtok_r(hourStr,dotDelim,&strtokPtr));
	gpsData->latVal1=atoi((char *)strtok_r(latStr,dotDelim,&strtokPtr));
	gpsData->latVal2=atoi((char *)strtok_r(NULL,dotDelim,&strtokPtr));
	gpsData->longVal1=atoi((char *)strtok_r(longStr,dotDelim,&strtokPtr));
	gpsData->longVal2=atoi((char *)strtok_r(NULL,dotDelim,&strtokPtr));
	gpsData->altVal1=atoi((char *)strtok_r(altStr,dotDelim,&strtokPtr));
	gpsData->altVal2=atoi((char *)strtok_r(NULL,dotDelim,&strtokPtr));

	/*printf("Hour : %d; Lat : %d.%d, %c; long : %d.%d, %c; alt : %d.%d\n", gpsData->hour, gpsData->latVal1, gpsData->latVal2, gpsData->latLetter, gpsData->longVal1, gpsData->longVal2, gpsData->longLetter, gpsData->altVal1, gpsData->altVal2);*/
	
}
